package com.ruoyi.common.core.serializer;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.ruoyi.common.core.annotation.jackson.JsonFormatCustomer;
import com.ruoyi.common.core.utils.CommonUtils;
import java.io.IOException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * <p>
 * 作用：时间返序列
 * </p>
 *
 * @author zhanglianbao
 * @since 2025-02-08 13:44
 */
public class LocalTimeDeserializer extends JsonDeserializer<LocalTime>
    implements ContextualDeserializer {

  final ConcurrentMap<String, LocalTimeDeserializer> deserializers = new ConcurrentHashMap<>();
  private DateTimeFormatter formatter;

  // 默认构造函数
  public LocalTimeDeserializer() {
    this(DateTimeFormatter.ofPattern("HH:mm:ss"));
  }

  // 带格式的构造函数
  public LocalTimeDeserializer(DateTimeFormatter formatter) {
    this.formatter = formatter;
  }

  @Override
  public LocalTime deserialize(JsonParser p, DeserializationContext ctxt)
      throws IOException, JacksonException {
    return LocalTime.parse(p.getText(), formatter);
  }

  @Override
  public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
      throws JsonMappingException {
    // 检查是否有自定义的格式化注解
    JsonFormatCustomer formatCustomer = property.getAnnotation(JsonFormatCustomer.class);
    if (formatCustomer != null && CommonUtils.hasText(formatCustomer.pattern())) {
      // 如果有自定义的格式化注解，返回一个新的序列化器实例
      if (deserializers.containsKey(formatCustomer.pattern())) {
        return deserializers.get(formatCustomer.pattern());
      } else {
        final LocalTimeDeserializer deserializer = new LocalTimeDeserializer(
            DateTimeFormatter.ofPattern(formatCustomer.pattern()));
        deserializers.putIfAbsent(formatCustomer.pattern(), deserializer);
        return deserializer;
      }
    }
    return this;
  }
}
